﻿using SelfMadeMillionaire.Core;
using SelfMadeMillionaire.Core.Entities;
using SelfMadeMillionaire.Core.Enums;
using SelfMadeMillionaire.Core.Services;
using SelfMadeMillionaire.Web.Infrastructure.Controllers;
using SelfMadeMillionaire.Web.Infrastructure.Formatters;
using SelfMadeMillionaire.Web.Infrastructure.ViewModels.Newsletters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using PagedList;
using System.Globalization;

namespace SelfMadeMillionaire.Web.Infrastructure.Controllers.Admin
{
	public class NewslettersController : AdminController
	{
		INewsletterService _newsletterService;
        INewsletterProductService _newsletterProductService;
        IEmailService _emailService;
        IMailingListService _mailingListService;

        public NewslettersController(INewsletterService newsletterService, IMailingListService mailingListService, IEmailService emailService, INewsletterProductService newsletterProductService)
		{
			_newsletterService = newsletterService;
            _newsletterProductService = newsletterProductService;
            _mailingListService = mailingListService;
            _emailService = emailService;
		}

        class NewslettersFilterSave
        {
            public DateTime? StartDate;
            public DateTime? EndDate;
            public ProductType? SelectedProduct;
            public byte? IssueType;
            public string Symbols;
            public string Title;
            public int? Page;
            public byte? MinAccessLevel;
            public string Sort;
        }

        public ActionResult Index(DateTime? startDate, DateTime? endDate, ProductType? selectedProduct, byte? issueType, string symbols, string title, int? page, byte? minAccessLevel, string sort)
		{
            if (Session["UseNewslettersFilter"] != null && Session["NewslettersFilter"] != null)
            {
                Session["UseNewslettersFilter"] = null;
                var filter = Session["NewslettersFilter"] as NewslettersFilterSave;

                startDate = filter.StartDate;
                endDate = filter.EndDate;
                selectedProduct = filter.SelectedProduct;
                issueType = filter.IssueType;
                symbols = filter.Symbols;
                title = filter.Title;
                page = filter.Page;
                minAccessLevel = filter.MinAccessLevel;
                sort = filter.Sort;
            }
            else
            {
                Session["NewslettersFilter"] = new NewslettersFilterSave()
                {
                    EndDate = endDate,
                    IssueType = issueType,
                    MinAccessLevel = minAccessLevel,
                    Page = page,
                    SelectedProduct = selectedProduct,
                    Sort = sort,
                    StartDate = startDate,
                    Symbols = symbols,
                    Title = title
                };
            }


			int pageIndex = page ?? 1;
			int pageSize = 10;

			var issueTypes = _newsletterService.GetIssueTypes();

			startDate = startDate ?? DateTime.Today.AddMonths(-1);
			endDate = endDate ?? DateTime.Today;

            var isUS = IsUsIP();

			var model = new NewsletterListViewModel
			{
                IsSendLinkVisible = isUS,
				StartDate = startDate,
				EndDate = endDate,
				ProductTypes = GetProductTypes(selectedProduct),
				IssueTypes = GetIssueTypes(issueTypes, issueType.HasValue ? issueType.ToString() : null),
				AccessLevels = GetAccessLevelsFilter(minAccessLevel.HasValue? minAccessLevel.ToString() : null),
				Symbols = symbols,
				Title = title,
				EditModel = new NewsletterEditViewModel
							   {
								   IssueTypes = GetIssueTypes(issueTypes),
								   ProductTypes = GetProductTypes(),
								   Date = DateTime.Now,
								   AccessLevels = GetAccessLevels(null),
                                   SelectedProducts = new List<int>()
							   },
                SortOrder = sort
			};

            IEnumerable<Newsletter> list = _newsletterService.GetList(startDate, endDate, selectedProduct, issueType, symbols, title, null, minAccessLevel, true);
            if (!string.IsNullOrEmpty(sort))
            {
                string[] sortArr = sort.Split(',');
                if (sortArr[1] == "0")
                {

                    switch (sortArr[0])
                    {
                        case "0":
                            list = list.OrderBy(i => i.Date);
                            break;
                        case "1":
                            list = list.OrderBy(i => i.IssueType.Title);
                            break;
                        case "2":
                            list = list.OrderBy(i => i.Symbols);
                            break;
                        case "3":
                            list = list.OrderBy(i => ProductTypeFormatter.GetProductTypeName((ProductType)Enum.Parse(typeof(ProductType), i.Letter.ToString())));
                            break;
                        case "4":
                            list = list.OrderBy(i => i.Title);
                            break;
                        case "5":
                            list = list.OrderBy(i => i.MinAccessLevelOriginal);
                            break;
                        case "6":
                            list = list.OrderBy(i => i.EmailMessage==null?DateTime.MinValue:i.EmailMessage.DateSent);
                            break;
                    }
                    
                }
                else
                {
                    switch (sortArr[0])
                    {
                        case "0":
                            list = list.OrderByDescending(i => i.Date);
                            break;
                        case "1":
                            list = list.OrderByDescending(i => i.IssueType.Title);
                            break;
                        case "2":
                            list = list.OrderByDescending(i => i.Symbols);
                            break;
                        case "3":
                            list = list.OrderByDescending(i => ProductTypeFormatter.GetProductTypeName((ProductType)Enum.Parse(typeof(ProductType), i.Letter.ToString())));
                            break;
                        case "4":
                            list = list.OrderByDescending(i => i.Title);
                            break;
                        case "5":
                            list = list.OrderByDescending(i => i.MinAccessLevelOriginal);
                            break;
                        case "6":
                            list = list.OrderByDescending(i => i.EmailMessage == null ? DateTime.MinValue : i.EmailMessage.DateSent);
                            break;
                    }
                }
            }
            model.Newsletters = list.ToPagedList(pageIndex, pageSize);
            
            if (Request.IsAjaxRequest())
				return PartialView("NewslettersList", model);

			return View(model);
		}


		[HttpPost]
		public ActionResult Add(NewsletterEditViewModel model)
		{
			if (ModelState.IsValid)
			{
				var newsletter = new Newsletter
				{
					Title = model.Title,
					Symbols = model.Symbols,
					IssueType = _newsletterService.GetIssueTypes().Single(x => x.ID == model.IssueType),
					Letter = model.Letter,
					Date = model.Date,
					MinAccessLevel = (byte)SubscriptionType.Platinum,
                    MinAccessLevelOriginal = model.MinAccessLevel
				};

				if (model.PdfFile != null)
				{
					model.PdfFile.SaveAs(FileLink.GetSaveFilePath(model.PdfFile.FileName));
					newsletter.PdfFileName = model.PdfFile.FileName;
				}

                newsletter.Products = new List<NewsletterProduct>();
                if (model.SelectedProducts != null)
                {
                    model.SelectedProducts.ForEach(x => newsletter.Products.Add(new NewsletterProduct() { ProductType = (byte)x }));
                }

				_newsletterService.Add(newsletter);
                Session["UseNewslettersFilter"] = true;
				return RedirectToAction("Index");
			}

			var issueTypes = _newsletterService.GetIssueTypes();
			model.IssueTypes = GetIssueTypes(issueTypes, model.IssueType.ToString());
			model.ProductTypes = GetProductTypes((ProductType)model.Letter);
			model.AccessLevels = GetAccessLevels(model.MinAccessLevel);

			return View(model);
		}


		[HttpGet]
		public ActionResult Edit(int id)
		{
			var newsletter = _newsletterService.Get(id);
			var issueTypes = _newsletterService.GetIssueTypes();

			var model = new NewsletterEditViewModel
			{
				ID = newsletter.ID,
				Title = newsletter.Title,
				Symbols = newsletter.Symbols,
				IssueType = newsletter.IssueType.ID,
				Letter = newsletter.Letter,
				PdfFileName = newsletter.PdfFileName,
				IssueTypes = GetIssueTypes(issueTypes, newsletter.IssueType.ToString()),
				ProductTypes = GetProductTypes((ProductType)newsletter.Letter),
				Date = newsletter.Date,
				MinAccessLevel = newsletter.MinAccessLevelOriginal,
				AccessLevels = GetAccessLevels(null),
                SelectedProducts = newsletter.Products.Select(x => (int)x.ProductType).ToList()
			};

            Session["UseNewslettersFilter"] = true;
			return View(model);
		}

		[HttpPost]
		public ActionResult Edit(NewsletterEditViewModel model)
		{
			if (ModelState.IsValid)
			{
				var newsletter = new Newsletter
				{
					ID = model.ID,
					Title = model.Title,
					Symbols = model.Symbols,
					IssueType = _newsletterService.GetIssueTypes().Single(x => x.ID == model.IssueType),
					Letter = model.Letter,
					PdfFileName = model.PdfFileName,
					Date = model.Date,
                    MinAccessLevelOriginal = model.MinAccessLevel,
                    MinAccessLevel = (byte)SubscriptionType.Platinum,
				};

				if (model.PdfFile != null)
				{
					model.PdfFile.SaveAs(FileLink.GetSaveFilePath(model.PdfFile.FileName));
					newsletter.PdfFileName = model.PdfFile.FileName;
				}

                newsletter.Products = _newsletterService.Get(model.ID).Products;
                newsletter.Products.ToList().ForEach(x => _newsletterProductService.Remove(x.ID));
                if (model.SelectedProducts != null)
                    model.SelectedProducts.ForEach(x => newsletter.Products.Add(new NewsletterProduct() { ProductType = (byte)x }));

				_newsletterService.Update(newsletter);
				return RedirectToAction("Index");
			}

			var issueTypes = _newsletterService.GetIssueTypes();
			model.IssueTypes = GetIssueTypes(issueTypes, model.IssueType.ToString());
			model.ProductTypes = GetProductTypes((ProductType)model.Letter);
			model.AccessLevels = GetAccessLevels(model.MinAccessLevel);

			return View(model);
		}

		/*[HttpGet]
		public ActionResult Delete(int id)
		{
			_newsletterService.Remove(id);

			return RedirectToAction("Index");
		}*/

        [HttpGet]
        public string Delete(int id)
        {
            _newsletterService.Remove(id);
            return "Completed successfully!";
        }

        [HttpGet]
        public string Hide(int id)
        {
            _newsletterService.Hide(id);
            return "Completed successfully!";
        }

        [HttpGet]
        public string Show(int id)
        {
            _newsletterService.Show(id);
            return "Completed successfully!";
        }

		[HttpGet]
        public string Send(int id)
		{
			string emailTemplate = System.IO.File.ReadAllText(Server.MapPath("~/EmailTemplates/Subscription.html"));
            _newsletterService.Send(id, emailTemplate);
            return "Completed successfully!";
		}

        [HttpGet]
        public string SendTester(int id)
        {
            Newsletter newsletter = _newsletterService.Get(id);
            string emailTemplate = System.IO.File.ReadAllText(Server.MapPath("~/EmailTemplates/Subscription.html"));
            string body = emailTemplate
                .Replace("[issueTypeName]", newsletter.IssueType.Title)
                .Replace("[currentYear]", DateTime.Now.Year.ToString(CultureInfo.InvariantCulture));
            string subject = string.Format("{0}!", newsletter.IssueType.Title);
            List<Subscriber> sList = _mailingListService.GetSubscribersTester().ToList();
            foreach (Subscriber s in sList)
            {
                _emailService.SendEmailFromSupport(s.Email, subject, body);
            }
            
            return "Completed successfully!";
        }
	}
}
